import 'dart:math';

import 'package:flutter/foundation.dart';

import '../request/AL_HttpRequest.dart';
import 'KaL_LottoModel.dart';

class KaL_DataViewModels {
  // 单例
  factory KaL_DataViewModels() => _getInstance()!;
  static KaL_DataViewModels get instance => _getInstance()!;
  static KaL_DataViewModels? _instance;
  KaL_DataViewModels._internal();
  static KaL_DataViewModels? _getInstance() {
    _instance ??= KaL_DataViewModels._internal();
    return _instance;
  }

  late var AL_lottoInfo = {}; //当前彩种数据
  late var AL_lottoModel = KaL_LottoModel(); //当前彩种模型数据

  late var EJ_models = []; //全部结果模型数组
  late var EJ_lottoResults = []; //全部结果数据集合
  late var EJ_draws_date = []; //全部开奖日期

  late var EJ_CalculateTitles = [];
  late var EJ_topTitles = []; //analytics列表顶部title
  late var EJ_ballsResults = []; //匹配每期开奖结果
  late var EJ_CalculatedDrawings = []; //号码中奖次数
  late var EJ_AverageSkipping = []; //平均遗漏
  late var EJ_MaximumSkipping = []; //最大遗漏→
  late var EJ_MaximumConsecution = []; //最大连开→
  late var EJ_ChooseNumbers = []; //待选号码

  //获取数据
  Future<bool> getData(int pageSize) async {
    // final response = await dio.get('https://dart.dev');
    var response = await ALHttprequest().getData(pageSize);
    debugPrint('$response');

    int status = response['status'];
    Map data = response['data'];
    // Map data = jsonDecode(response['data']);
    if (status == 200 && data.isNotEmpty) {
      AL_lottoInfo = data['lottoInfo'];
      List results = data['lottoResults'];
      EJ_lottoResults = results.reversed.toList();
      AL_lottoModel = KaL_LottoModel.fromJson(AL_lottoInfo);

      EJ_getCalculateTitle();

      ///
      EJ_getResultsOfModel();

      ///
      EJ_getAnalyticsTopTitles();

      ///
      EJ_getAnalyticsResults();

      ///
      EJ_getCalculatedDrawings();

      return true;
    }
    return false;
  }

  EJ_getCalculateTitle() {
    var titles = [
      'Drawn\nCount',
      'Average\nSkipping',
      'Maximum\nSkipping',
      'Maximum\nConsecution',
      'Choose &\nSave Ticket',
    ];
    EJ_CalculateTitles = titles;
    return titles;
  }

  //map to model
  EJ_getResultsOfModel() {
    EJ_models.clear();
    EJ_draws_date.clear();
    var draws_dates = [];
    if (EJ_lottoResults.isNotEmpty) {
      for (var element in EJ_lottoResults) {
        var model = KaL_LottoModel.fromJson(element);
        EJ_models.add(model);
        draws_dates.add(model.drawtime);
      }
      EJ_draws_date = draws_dates;
    }
    return EJ_models;
  }

  //顶部号码
  EJ_getAnalyticsTopTitles() {
    var titles = [];
    EJ_topTitles.clear();
    for (var i = 1; i <= AL_lottoModel.regularnumbermax; i++) {
      titles.add(i.toString());
    }
    for (var i = 1; i <= AL_lottoModel.extranumbermax; i++) {
      titles.add(i.toString());
    }
    EJ_topTitles = titles;
  }

  //匹配Analytics每一行开奖结果
  EJ_getAnalyticsResults() {
    EJ_ballsResults.clear();
    var results = [];

    var lottoResultDatas = EJ_lottoResults.reversed.toList();
    for (var i = 0; i < lottoResultDatas.length; i++) {
      var element = lottoResultDatas[i];
      var balls = [];

      ///regular
      for (var j = 1; j <= AL_lottoModel.regularnumbermax; j++) {
        var isRightNum = false;
        int jStr = 1;
        if (i > 0) {
          for (var k = 0; k < results.length; k++) {
            List list = results[k];
            Map ball = list[j - 1];
            isRightNum = ball['isRightNum'] > 0 ? true : false;
            var number = int.parse(ball['number']);
            //往上的期找，如果找到中奖的号，下一期号码就从1开始
            if (isRightNum) {
              jStr = 1;
            } else {
              jStr = number + 1;
            }
            // jStr++;
          }
          // debugPrint('jStr--$jStr');
        }

        var unSeltBall = {
          "number": jStr.toString(),
          "isRightNum": 0,
          "regularnumber": 1,
          "hasBorder": 1
        };
        List regularnumbers = element['regularnumbers'];
        if (regularnumbers.contains(j.toString())) {
          //当前中的号码就取号码
          var seltBall = {
            "number": j.toString(),
            "isRightNum": 1,
            "regularnumber": 1,
            "hasBorder": 1
          };
          balls.add(seltBall);
        } else {
          balls.add(unSeltBall); //没中的号码就取序号
        }
      }

      ///extra
      for (var j = 1; j <= AL_lottoModel.extranumbermax; j++) {
        var isRightNum = false;
        int jStr = 1;
        if (i > 0) {
          for (var k = 0; k < results.length; k++) {
            List list = results[k];
            int jIndex = list.length -
                int.parse(AL_lottoModel.extranumbermax.toString());
            Map ball = list[jIndex + j - 1];
            isRightNum = ball['isRightNum'] > 0 ? true : false;
            var number = int.parse(ball['number']);
            //往上的期找，如果找到中奖的号，下一期号码就从1开始
            if (isRightNum) {
              jStr = 1;
            } else {
              jStr = number + 1;
            }
            // jStr++;
          }
          // debugPrint('jStr--$jStr');
        }

        var unSeltBall = {
          "number": jStr.toString(),
          "isRightNum": 0,
          "regularnumber": 0,
          "hasBorder": 1
        };
        List extranumbers = element['extranumbers'];
        if (extranumbers.contains(j.toString())) {
          //当前中的号码就取号码
          var seltBall = {
            "number": j.toString(),
            "isRightNum": 1,
            "regularnumber": 0,
            "hasBorder": 1
          };
          balls.add(seltBall);
        } else {
          balls.add(unSeltBall); //没中的号码就取序号
        }
      }

      ///
      results.add(balls);
    }

    // EJ_ballsResults = results.reversed.toList();
    EJ_ballsResults = results;
    return EJ_ballsResults;
  }

  EJ_getCalculatedDrawings() {
    EJ_CalculatedDrawings.clear();
    var results = [];

    ///regular
    for (var i = 1; i <= AL_lottoModel.regularnumbermax; i++) {
      int count = 0;
      for (var element in EJ_lottoResults) {
        List regularnumbers = element['regularnumbers'];
        if (regularnumbers.contains(i.toString())) {
          count++;
        }
      }
      var number = {
        "number": count.toString(),
        "isRightNum": 0,
        "regularnumber": 0,
        "hasBorder": 0
      };
      results.add(number);
    }

    ///extra
    for (var j = 1; j <= AL_lottoModel.extranumbermax; j++) {
      int count = 0;
      for (var element in EJ_lottoResults) {
        List extranumbers = element['extranumbers'];
        if (extranumbers.contains(j.toString())) {
          count++;
        }
      }
      var number = {
        "number": count.toString(),
        "isRightNum": 0,
        "regularnumber": 0,
        "hasBorder": 0
      };
      results.add(number);
    }
    EJ_CalculatedDrawings = results;
    EJ_getAverageSkipping();
    EJ_getMaximumSkipping();
    EJ_getMaximumConsecution();
    getChoosingNumber();
    return results;
  }

  ///计算平均遗漏
  EJ_getAverageSkipping() {
    var results = [];
    for (var i = 0; i < EJ_CalculatedDrawings.length; i++) {
      var count;
      if (i <= 68) {
        // int element = EJ_CalculatedDrawings[i];
        count = (69 / 5 - 1).round().toString(); //四舍五入后转string
      } else {
        count = (26 / 1 - 1).round().toString();
      }
      var number = {
        "number": count,
        "isRightNum": 0,
        "regularnumber": 0,
        "hasBorder": 0
      };
      results.add(number);
    }
    EJ_AverageSkipping = results;
    return results;
  }

  ///计算最大遗漏
  EJ_getMaximumSkipping() {
    EJ_MaximumSkipping.clear();
    var results = [];

    ///regular
    for (var i = 1; i <= AL_lottoModel.regularnumbermax; i++) {
      int count = 0;
      var counts = [
        {"number": '0', "isRightNum": 0, "regularnumber": 0, "hasBorder": 0}
      ];
      for (var j = 0; j < EJ_lottoResults.length; j++) {
        Map element = EJ_lottoResults[j];
        List regularnumbers = element['regularnumbers'];

        if (regularnumbers.contains(i.toString())) {
          // int oldCount = counts[0];
          Map oldNumber = counts[0] as Map;
          int oldCount = int.parse(oldNumber['number']);
          if (count > oldCount) {
            counts.remove(oldNumber);
            var number = {
              "number": count.toString(),
              "isRightNum": 0,
              "regularnumber": 0,
              "hasBorder": 0
            };
            counts.add(number);
          }
          count = 0;
        } else {
          count++;
        }
        //计算到最后一个结果都没有中奖号
        if (j == EJ_lottoResults.length - 1) {
          Map oldNumber = counts[0] as Map;
          int oldCount = int.parse(oldNumber['number']);
          if (count > oldCount) {
            counts.remove(oldNumber);
            var number = {
              "number": count.toString(),
              "isRightNum": 0,
              "regularnumber": 0,
              "hasBorder": 0
            };
            counts.add(number);
          }
        }
      }
      results.addAll(counts);
    }

    ///extranumbers
    for (var i = 1; i <= AL_lottoModel.extranumbermax; i++) {
      int count = 0;
      var counts = [
        {"number": '0', "isRightNum": 0, "regularnumber": 0, "hasBorder": 0}
      ];
      for (var j = 0; j < EJ_lottoResults.length; j++) {
        Map element = EJ_lottoResults[j];
        List extranumbers = element['extranumbers'];

        if (extranumbers.contains(i.toString())) {
          Map oldNumber = counts[0] as Map;
          int oldCount = int.parse(oldNumber['number']);
          if (count > oldCount) {
            counts.remove(oldNumber);
            var number = {
              "number": count.toString(),
              "isRightNum": 0,
              "regularnumber": 0,
              "hasBorder": 0
            };
            counts.add(number);
          }
          count = 0;
        } else {
          count++;
        }
        //计算到最后一个结果都没有中奖号
        if (j == EJ_lottoResults.length - 1) {
          Map oldNumber = counts[0] as Map;
          int oldCount = int.parse(oldNumber['number']);
          if (count > oldCount) {
            counts.remove(oldNumber);
            var number = {
              "number": count.toString(),
              "isRightNum": 0,
              "regularnumber": 0,
              "hasBorder": 0
            };
            counts.add(number);
          }
        }
      }
      results.addAll(counts);
    }

    EJ_MaximumSkipping = results;
    return results;
  }

  ///获取最大连开
  EJ_getMaximumConsecution() {
    EJ_MaximumConsecution.clear();
    var results = [];

    ///regular
    for (var i = 1; i <= AL_lottoModel.regularnumbermax; i++) {
      int count = 0;
      var counts = [
        {"number": '0', "isRightNum": 0, "regularnumber": 0, "hasBorder": 0}
      ];
      for (var j = 0; j < EJ_lottoResults.length; j++) {
        Map element = EJ_lottoResults[j];
        List regularnumbers = element['regularnumbers'];

        if (regularnumbers.contains(i.toString())) {
          count++;
          Map oldNumber = counts[0] as Map;
          int oldCount = int.parse(oldNumber['number']);
          if (count > oldCount) {
            counts.remove(oldNumber);
            var number = {
              "number": count.toString(),
              "isRightNum": 0,
              "regularnumber": 0,
              "hasBorder": 0
            };
            counts.add(number);
          }
        } else {
          count = 0;
        }
      }
      results.addAll(counts);
    }

    ///extranumbers
    for (var i = 1; i <= AL_lottoModel.extranumbermax; i++) {
      int count = 0;
      var counts = [
        {"number": '0', "isRightNum": 0, "regularnumber": 0, "hasBorder": 0}
      ];
      for (var j = 0; j < EJ_lottoResults.length; j++) {
        Map element = EJ_lottoResults[j];
        List extranumbers = element['extranumbers'];

        if (extranumbers.contains(i.toString())) {
          count++;
          Map oldNumber = counts[0] as Map;
          int oldCount = int.parse(oldNumber['number']);
          if (count > oldCount) {
            counts.remove(oldNumber);
            var number = {
              "number": count.toString(),
              "isRightNum": 0,
              "regularnumber": 0,
              "hasBorder": 0
            };
            counts.add(number);
          }
        } else {
          count = 0;
        }
      }
      results.addAll(counts);
    }
    EJ_MaximumConsecution = results;
    return EJ_MaximumConsecution;
  }

  ///选号栏
  getChoosingNumber() {
    EJ_ChooseNumbers.clear();
    var numbers = [];

    ///regular
    for (var i = 1; i <= AL_lottoModel.regularnumbermax; i++) {
      var number = {
        "redBall": 1,
        "number": i.toString(),
        "isRightNum": 0,
        "regularnumber": 1,
        "hasBorder": 1
      };
      numbers.add(number);
    }

    ///extranumbers
    for (var i = 1; i <= AL_lottoModel.extranumbermax; i++) {
      var number = {
        "redBall": 0,
        "number": i.toString(),
        "isRightNum": 0,
        "regularnumber": 0,
        "hasBorder": 1
      };
      numbers.add(number);
    }
    EJ_ChooseNumbers = numbers;
    return numbers;
  }

  ///随机生成号码
  List<int> generateUniqueRandomSortedNumbers(int min, int max, int count) {
    if (count > (max - min + 1)) {
      throw Exception(
          'Count must be less than or equal to the range of numbers.');
    }

    List<int> numbers = [];
    Random random = Random();

    while (numbers.length < count) {
      int randomNumber = min + random.nextInt(max - min + 1);
      if (!numbers.contains(randomNumber)) {
        numbers.add(randomNumber);
      }
    }

    numbers.sort(); // 对生成的数字列表进行排序

    return numbers;
  }
}
